{
  "cells": [
    {
      "cell_type": "raw",
      "id": "afaf8039",
      "metadata": {
        "vscode": {
          "languageId": "raw"
        }
      },
      "source": [
        "---\n",
        "sidebar_label: IBM watsonx.ai\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e49f1e0d",
      "metadata": {},
      "source": [
        "# IBM watsonx.ai\n",
        "\n",
        "This will help you getting started with IBM watsonx.ai [chat models](/docs/concepts/chat_models). For detailed documentation of all `IBM watsonx.ai` features and configurations head to the [IBM watsonx.ai](https://api.js.langchain.com/modules/_langchain_community.chat_models_ibm.html).\n",
        "\n",
        "## Overview\n",
        "### Integration details\n",
        "\n",
        "| Class | Package | Local | Serializable | [PY support](https://python.langchain.com/docs/integrations/chat/ibm_watsonx/) | Package downloads | Package latest |\n",
        "| :--- | :--- | :---: | :---: |  :---: | :---: | :---: |\n",
        "| [`ChatWatsonx`](https://api.js.langchain.com/classes/_langchain_community.chat_models_ibm.ChatWatsonx.html) | [@langchain/community](https://www.npmjs.com/package/@langchain/community) | ❌ | ✅ | ✅ | ![NPM - Downloads](https://img.shields.io/npm/dm/@langchain/community?style=flat-square&label=%20&) | ![NPM - Version](https://img.shields.io/npm/v/@langchain/community?style=flat-square&label=%20&) |\n",
        "\n",
        "### Model features\n",
        "\n",
        "\n",
        "| [Tool calling](/docs/how_to/tool_calling) | [Structured output](/docs/how_to/structured_output/) | JSON mode | [Image input](/docs/how_to/multimodal_inputs/) | Audio input | Video input | [Token-level streaming](/docs/how_to/chat_streaming/) | [Token usage](/docs/how_to/chat_token_usage_tracking/) | [Logprobs](/docs/how_to/logprobs/) |\n",
        "| :---: | :---: | :---: | :---: |  :---: | :---: | :---: | :---: | :---: |\n",
        "| ✅ | ✅ | ✅  | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | \n",
        "\n",
        "## Setup\n",
        "\n",
        "To access IBM watsonx.ai models you'll need to create a/an IBM watsonx.ai account, get an API key, and install the `@langchain/community` integration package.\n",
        "\n",
        "### Credentials\n",
        "\n",
        "\n",
        "Head to [IBM Cloud](https://cloud.ibm.com/login) to sign up to IBM watsonx.ai and generate an API key or provide any other authentication form as presented below.\n",
        "\n",
        "#### IAM authentication\n",
        "\n",
        "```bash\n",
        "export WATSONX_AI_AUTH_TYPE=iam\n",
        "export WATSONX_AI_APIKEY=<YOUR-APIKEY>\n",
        "```\n",
        "\n",
        "#### Bearer token authentication\n",
        "\n",
        "```bash\n",
        "export WATSONX_AI_AUTH_TYPE=bearertoken\n",
        "export WATSONX_AI_BEARER_TOKEN=<YOUR-BEARER-TOKEN>\n",
        "```\n",
        "\n",
        "#### IBM watsonx.ai software authentication\n",
        "\n",
        "```bash\n",
        "export WATSONX_AI_AUTH_TYPE=cp4d\n",
        "export WATSONX_AI_USERNAME=<YOUR_USERNAME>\n",
        "export WATSONX_AI_PASSWORD=<YOUR_PASSWORD>\n",
        "export WATSONX_AI_URL=<URL>\n",
        "```\n",
        "\n",
        "Once these are places in your enviromental variables and object is initialized authentication will proceed automatically.\n",
        "\n",
        "Authentication can also be accomplished by passing these values as parameters to a new instance.\n",
        "\n",
        "## IAM authentication\n",
        "\n",
        "```typescript\n",
        "import { WatsonxLLM } from \"@langchain/community/llms/ibm\";\n",
        "\n",
        "const props = {\n",
        "  version: \"YYYY-MM-DD\",\n",
        "  serviceUrl: \"<SERVICE_URL>\",\n",
        "  projectId: \"<PROJECT_ID>\",\n",
        "  watsonxAIAuthType: \"iam\",\n",
        "  watsonxAIApikey: \"<YOUR-APIKEY>\",\n",
        "};\n",
        "const instance = new WatsonxLLM(props);\n",
        "```\n",
        "\n",
        "## Bearer token authentication\n",
        "\n",
        "```typescript\n",
        "import { WatsonxLLM } from \"@langchain/community/llms/ibm\";\n",
        "\n",
        "const props = {\n",
        "  version: \"YYYY-MM-DD\",\n",
        "  serviceUrl: \"<SERVICE_URL>\",\n",
        "  projectId: \"<PROJECT_ID>\",\n",
        "  watsonxAIAuthType: \"bearertoken\",\n",
        "  watsonxAIBearerToken: \"<YOUR-BEARERTOKEN>\",\n",
        "};\n",
        "const instance = new WatsonxLLM(props);\n",
        "```\n",
        "\n",
        "### IBM watsonx.ai software authentication\n",
        "\n",
        "```typescript\n",
        "import { WatsonxLLM } from \"@langchain/community/llms/ibm\";\n",
        "\n",
        "const props = {\n",
        "  version: \"YYYY-MM-DD\",\n",
        "  serviceUrl: \"<SERVICE_URL>\",\n",
        "  projectId: \"<PROJECT_ID>\",\n",
        "  watsonxAIAuthType: \"cp4d\",\n",
        "  watsonxAIUsername: \"<YOUR-USERNAME>\",\n",
        "  watsonxAIPassword: \"<YOUR-PASSWORD>\",\n",
        "  watsonxAIUrl: \"<url>\",\n",
        "};\n",
        "const instance = new WatsonxLLM(props);\n",
        "```\n",
        "\n",
        "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
        "\n",
        "```bash\n",
        "# export LANGSMITH_TRACING=\"true\"\n",
        "# export LANGSMITH_API_KEY=\"your-api-key\"\n",
        "```\n",
        "\n",
        "### Installation\n",
        "\n",
        "The LangChain IBM watsonx.ai integration lives in the `@langchain/community` package:\n",
        "\n",
        "```{=mdx}\n",
        "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
        "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
        "\n",
        "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
        "\n",
        "<Npm2Yarn>\n",
        "  @langchain/community @langchain/core\n",
        "</Npm2Yarn>\n",
        "\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a38cde65-254d-4219-a441-068766c0d4b5",
      "metadata": {},
      "source": [
        "## Instantiation\n",
        "\n",
        "Now we can instantiate our model object and generate chat completions:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { ChatWatsonx } from \"@langchain/community/chat_models/ibm\";\n",
        "const props = {\n",
        "  maxTokens: 200,\n",
        "  temperature: 0.5\n",
        "};\n",
        "\n",
        "const instance = new ChatWatsonx({\n",
        "  version: \"YYYY-MM-DD\",\n",
        "  serviceUrl: process.env.API_URL,\n",
        "  projectId: \"<PROJECT_ID>\",\n",
        "  // spaceId: \"<SPACE_ID>\",\n",
        "  // idOrName: \"<DEPLOYMENT_ID>\",\n",
        "  model: \"<MODEL_ID>\",\n",
        "  ...props\n",
        "});"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "30cb3968",
      "metadata": {},
      "source": [
        "Note:\n",
        "\n",
        "- You must provide `spaceId`, `projectId` or `idOrName`(deployment id) unless you use lighweight engine which works without specifying either (refer to [watsonx.ai docs](https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-choosing-installation-mode))\n",
        "- Depending on the region of your provisioned service instance, use correct serviceUrl."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2b4f3e15",
      "metadata": {},
      "source": [
        "## Invocation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "62e0dbc3",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"id\": \"chat-c5341b2062dc42f091e5ae2558e905e3\",\n",
            "  \"content\": \" J'adore la programmation.\",\n",
            "  \"additional_kwargs\": {\n",
            "    \"tool_calls\": []\n",
            "  },\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completion_tokens\": 10,\n",
            "      \"prompt_tokens\": 28,\n",
            "      \"total_tokens\": 38\n",
            "    },\n",
            "    \"finish_reason\": \"stop\"\n",
            "  },\n",
            "  \"tool_calls\": [],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 28,\n",
            "    \"output_tokens\": 10,\n",
            "    \"total_tokens\": 38\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "const aiMsg = await instance.invoke([{\n",
        "  role: \"system\",\n",
        "  content: \"You are a helpful assistant that translates English to French. Translate the user sentence.\",\n",
        "},\n",
        "{\n",
        "  role: \"user\",\n",
        "  content: \"I love programming.\"\n",
        "}]);\n",
        "console.log(aiMsg)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "d86145b3-bfef-46e8-b227-4dda5c9c2705",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " J'adore la programmation.\n"
          ]
        }
      ],
      "source": [
        "console.log(aiMsg.content)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "18e2bfc0-7e78-4528-a73f-499ac150dca8",
      "metadata": {},
      "source": [
        "## Chaining\n",
        "\n",
        "We can [chain](/docs/how_to/sequence/) our model with a prompt template like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"id\": \"chat-c5c2c08d3c984254acc48225c39c6a08\",\n",
            "  \"content\": \" Ich liebe Programmieren.\",\n",
            "  \"additional_kwargs\": {\n",
            "    \"tool_calls\": []\n",
            "  },\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completion_tokens\": 8,\n",
            "      \"prompt_tokens\": 22,\n",
            "      \"total_tokens\": 30\n",
            "    },\n",
            "    \"finish_reason\": \"stop\"\n",
            "  },\n",
            "  \"tool_calls\": [],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 22,\n",
            "    \"output_tokens\": 8,\n",
            "    \"total_tokens\": 30\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
        "\n",
        "const prompt = ChatPromptTemplate.fromMessages(\n",
        "  [\n",
        "    [\n",
        "      \"system\",\n",
        "      \"You are a helpful assistant that translates {input_language} to {output_language}.\",\n",
        "    ],\n",
        "    [\"human\", \"{input}\"],\n",
        "  ]\n",
        ")\n",
        "const chain = prompt.pipe(instance);\n",
        "await chain.invoke(\n",
        "    {\n",
        "      input_language: \"English\",\n",
        "      output_language: \"German\",\n",
        "      input: \"I love programming.\",\n",
        "    }\n",
        "  )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2896aae5",
      "metadata": {},
      "source": [
        "## Streaming the Model output"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "cd21e356",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            " The\n",
            " Moon\n",
            " is\n",
            " Earth\n",
            "'\n",
            "s\n",
            " only\n",
            " natural\n",
            " satellite\n",
            " and\n"
          ]
        }
      ],
      "source": [
        "import { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n",
        "\n",
        "const messages = [\n",
        "    new SystemMessage('You are a helpful assistant which telling short-info about provided topic.'),\n",
        "    new HumanMessage(\"moon\")\n",
        "]\n",
        "const stream = await instance.stream(messages);\n",
        "for await(const chunk of stream){\n",
        "    console.log(chunk)\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "65ed0609",
      "metadata": {},
      "source": [
        "## Tool calling"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "f32f8cb0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"id\": \"chat-d2214d0bdb794483a213b3211cf0d819\",\n",
            "  \"content\": \"\",\n",
            "  \"additional_kwargs\": {\n",
            "    \"tool_calls\": [\n",
            "      {\n",
            "        \"id\": \"chatcmpl-tool-257f3d39532141b89178c2120f81f0cb\",\n",
            "        \"type\": \"function\",\n",
            "        \"function\": \"[Object]\"\n",
            "      }\n",
            "    ]\n",
            "  },\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completion_tokens\": 38,\n",
            "      \"prompt_tokens\": 177,\n",
            "      \"total_tokens\": 215\n",
            "    },\n",
            "    \"finish_reason\": \"tool_calls\"\n",
            "  },\n",
            "  \"tool_calls\": [\n",
            "    {\n",
            "      \"name\": \"calculator\",\n",
            "      \"args\": {\n",
            "        \"number1\": 3,\n",
            "        \"number2\": 12,\n",
            "        \"operation\": \"multiply\"\n",
            "      },\n",
            "      \"type\": \"tool_call\",\n",
            "      \"id\": \"chatcmpl-tool-257f3d39532141b89178c2120f81f0cb\"\n",
            "    }\n",
            "  ],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 177,\n",
            "    \"output_tokens\": 38,\n",
            "    \"total_tokens\": 215\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "import { tool } from \"@langchain/core/tools\";\n",
        "import { z } from \"zod\";\n",
        "\n",
        "const calculatorSchema = z.object({\n",
        "    operation: z\n",
        "      .enum([\"add\", \"subtract\", \"multiply\", \"divide\"])\n",
        "      .describe(\"The type of operation to execute.\"),\n",
        "    number1: z.number().describe(\"The first number to operate on.\"),\n",
        "    number2: z.number().describe(\"The second number to operate on.\"),\n",
        "  });\n",
        "  \n",
        "const calculatorTool = tool(\n",
        "async ({ operation, number1, number2 }) => {\n",
        "    if (operation === \"add\") {\n",
        "    return `${number1 + number2}`;\n",
        "    } else if (operation === \"subtract\") {\n",
        "    return `${number1 - number2}`;\n",
        "    } else if (operation === \"multiply\") {\n",
        "    return `${number1 * number2}`;\n",
        "    } else if (operation === \"divide\") {\n",
        "    return `${number1 / number2}`;\n",
        "    } else {\n",
        "    throw new Error(\"Invalid operation.\");\n",
        "    }\n",
        "},\n",
        "{\n",
        "    name: \"calculator\",\n",
        "    description: \"Can perform mathematical operations.\",\n",
        "    schema: calculatorSchema,\n",
        "}\n",
        ");\n",
        "\n",
        "const instanceWithTools = instance.bindTools([calculatorTool]);\n",
        "\n",
        "const res = await instanceWithTools.invoke(\"What is 3 * 12\");\n",
        "console.log(res)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6339db97",
      "metadata": {},
      "source": [
        "## API reference\n",
        "\n",
        "For detailed documentation of all `IBM watsonx.ai` features and configurations head to the API reference: [API docs](https://api.js.langchain.com/modules/_langchain_community.embeddings_ibm.html)"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "JavaScript (Node.js)",
      "language": "javascript",
      "name": "javascript"
    },
    "language_info": {
      "file_extension": ".js",
      "mimetype": "application/javascript",
      "name": "javascript",
      "version": "20.17.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
